package top.ninwoo.edgecenter.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.ninwoo.edgecenter.check.ClusterServiceCheck;
import top.ninwoo.edgecenter.register.EdgeNodeRegister;

@Slf4j
@Configuration
public class ZookeeperConfiguration implements ApplicationContextAware {
    private static final Logger LOG = LoggerFactory.getLogger(ZookeeperConfiguration.class);

    @Value("${zookeeper.url}")
    private String url;

    private ApplicationContext applicationContext = null;

    @Bean(destroyMethod = "close")
    public CuratorFramework zkClient() {
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.newClient(url, retryPolicy);
        try {
            LOG.info("Zookeeper客户端[{}]已经连接", url);
            client.start();
        } catch (Exception e) {
            LOG.error("Zookeeper客户端[{}]连接失败", url);
            e.printStackTrace();
        }
        return client;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Bean
    public ApplicationRunner applicationRunner() {
        return args -> {
            // 这里加入新的启动自检
            ClusterServiceCheck check = applicationContext.getBean(ClusterServiceCheck.class);
            try {
                check.createCluster();
                check.pingTest();
            } catch (Exception e) {
                // 测试流程失败
                log.error("测试流程失败{}", e);
                throw new RuntimeException("Error");
            } finally {
                check.delCluster();
                check.delNetworkTopo();
            }
            EdgeNodeRegister bean = applicationContext.getBean(EdgeNodeRegister.class);
            bean.registerNode();
        };
    }
}
